package cn.lut.mvc.config;

import cn.lut.constant.CrowdConstant;
import cn.lut.exception.LoginAcctAlreadyInUserException;
import cn.lut.exception.LoginAcctAlreadyInUserForUpdateException;
import cn.lut.exception.LoginFailedException;
import cn.lut.util.CrowdUtil;
import cn.lut.util.ResultEntity;
import com.google.gson.Gson;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.servlet.ModelAndView;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

/**
 * @user:dell
 * @date:2020年11月23 13:32
 */
//@ControllerAdvice表示当前类是一个基于注解的异常处理类
@ControllerAdvice
public class CrowdExceptionResolver {
    @ExceptionHandler(value = LoginAcctAlreadyInUserForUpdateException.class)
    public ModelAndView resolveLoginAcctAlreadyInUserForUpdateException(LoginAcctAlreadyInUserForUpdateException exception, HttpServletRequest request, HttpServletResponse response) throws IOException {
        String viewname="system-error";

        return commonResolve(viewname,exception,request,response);
    }
    @ExceptionHandler(value = LoginAcctAlreadyInUserException.class)
    public ModelAndView resolveLoginAcctAlreadyInUserException(LoginAcctAlreadyInUserException exception, HttpServletRequest request, HttpServletResponse response) throws IOException {
        String viewname="admin-add";

        return commonResolve(viewname,exception,request,response);
    }
    @ExceptionHandler(value = NullPointerException.class)
    public ModelAndView resolveNullPointException(NullPointerException exception, HttpServletRequest request, HttpServletResponse response) throws IOException {
        String viewname="system-error";

        return commonResolve(viewname,exception,request,response);
    }
    @ExceptionHandler(value = ArithmeticException.class)
    public ModelAndView resolve(ArithmeticException exception,HttpServletRequest request,HttpServletResponse response) throws IOException {
        String viewname="system-error";

        return commonResolve(viewname,exception,request,response);
    }
    @ExceptionHandler(value = LoginFailedException.class)
    public ModelAndView resolveLoginFailedException(LoginFailedException exception,HttpServletRequest request,HttpServletResponse response) throws IOException {
        String viewname="admin-login";

        return commonResolve(viewname,exception,request,response);
    }


    private ModelAndView commonResolve(String viewName, Exception exception, HttpServletRequest request, HttpServletResponse response) throws IOException {
        //        1.判断请求的类型
        boolean judgeResult = CrowdUtil.judgeRequestType(request);
//        2.如果是ajax请求
        if (judgeResult){
//            // 3.从当前异常对象中获取异常信息，创建resultEntity对象
            ResultEntity<Object> resultEntity = ResultEntity.failed(exception.getMessage());
//            创建json对象
            Gson gson=new Gson();
//            将resultEntity字符串转化为json对象
            String json = gson.toJson(resultEntity);
//            将json字符串作为响应体返回给浏览器
            response.getWriter().write(json);
//            由于上面已经通过原生的response对象返回了响应，因此不提供modelAndView
            // 返回 null，不给 SpringMVC 提供 ModelAndView 对象 // 这样 SpringMVC 就知道不需要框架解析视图来提供响应， 而是程序员自己提供了响应
            return  null;
        }
//        如果不是ajax请求对象
        ModelAndView mv = new ModelAndView();
        mv.addObject(CrowdConstant.ATTR_NAME_EXCEPTION,exception);
//        设置对应视图
        mv.setViewName(viewName);
        return  mv;
    }
}
